#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>
#include <QDebug>
#include <QThread>
#include <QByteArray>
#include <QString>
#include <QFile>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->toolBar->clear();
    ui->toolBar->addAction(tr("Config"),this,SLOT(showConfig()));
    ui->toolBar->addAction(tr("Help"),  this,SLOT(showHelp()));
    ui->toolBar->addAction(tr("Quit"),  this,SLOT(close()));

    activateTimer = new QTimer();
    activateTimer->setSingleShot(true);
    uart = new SerialGUI;

    connect(uart,SIGNAL(configValidChanged    (bool)),
            this,SLOT(  configStatusChanged   (bool)));
    connect(this,SIGNAL(setActivateStatus     (bool)),
            this,SLOT(  activateStatusChanged (bool)));
    connect(this,SIGNAL(setCheckStatus        (bool)),
            this,SLOT(  checkStatusChanged    (bool)));
    connect(this,SIGNAL(setLockStatus         (bool)),
            this,SLOT(  lockStatusChanged     (bool)));
    connect(uart,SIGNAL(hasNewLine            ()),
            this,SLOT(  newMsgReceived        ()));
    connect(this,SIGNAL(forceShutdownRemote   ()),
            this,SLOT(  on_stby_button_clicked()));

    connect(activateTimer,SIGNAL(timeout           ()),
            this         ,SLOT(  sendActivatePacket()));

    emit setActivateStatus(false);
    //back to shutdown status

    uart->readLastConfig();
    //load last uart config

}

MainWindow::~MainWindow()
{
    delete ui;
    delete activateTimer;
    delete uart;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    emit forceShutdownRemote();
    uart->close();

    qApp->quit();
}

void MainWindow::showHelp()
{
    QMessageBox msgbox(QMessageBox::Information,
                       tr("User Manual"),
                       tr("Test"),
                       QMessageBox::Ok);
    msgbox.exec();
}

void MainWindow::showConfig()
{
    emit forceShutdownRemote();
    //standby remote
    uart->execConfigDialog();
}

void MainWindow::lockStatusChanged(bool isLocked)
{
    if(isLocked)
    {
        //ui->statusBar->showMessage(tr("Locked"));
        //ui->statusBar->setStyleSheet("color: red;");

        ui->lock_status->setStyleSheet(
            "border: 2px solid rgb(60,0,0);"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
            "qradialgradient("
                 "spread:pad, cx:0.5, cy:0.5,"
                 "radius:1.0,fx:0.5, fy:0.5,"
                 "stop:0.5 rgb(240, 0, 0),"
                 "stop:0.9 grey);"
            "color: rgb(60,0,0);");
        //set to red
        ui->lock_status->setText(tr("LOCKED"));
        ui->unlock_button->setText(tr("UNLOCK"));
    }
    else
    {
        //ui->statusBar->showMessage(tr("Unlocked"));
        //ui->statusBar->setStyleSheet("color: black;");

        ui->lock_status->setStyleSheet(
            "border: 2px solid rgb(0,60,0);"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
            "qradialgradient("
                 "spread:pad, cx:0.5, cy:0.5,"
                 "radius:1.0,fx:0.5, fy:0.5,"
                 "stop:0.5 rgb(0, 240, 0),"
                 "stop:0.9 grey);"
            "color: rgb(0,60,0);");
        //set to green
        ui->lock_status->setText(tr("UNLOCKED"));
        ui->unlock_button->setText(tr("RELOCK"));
    }
}

void MainWindow::checkStatusChanged(bool isChecked)
{
    if(isChecked)
    {
        ui->statusBar->showMessage(tr("Check passed"));
        ui->statusBar->setStyleSheet("color: black;");

        ui->check_status->setStyleSheet(
            "border: 2px solid rgb(0,60,0);"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
                "qradialgradient("
                "spread:pad, cx:0.5, cy:0.5,"
                "radius:1.0,fx:0.5, fy:0.5,"
                    "stop:0.5 rgb(0, 240, 0),"
                    "stop:0.9 grey);"
                    "color: rgb(0,60,0);");
        //set to green
        ui->check_status->setText(tr("PASSED"));
        ui->ignition_button->setEnabled(true);
    }
    else
    {
        ui->statusBar->showMessage(tr("Check error"));
        ui->statusBar->setStyleSheet("color: red;");

        ui->check_status->setStyleSheet(
            "border: 2px solid rgb(60,0,0);"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
            "qradialgradient("
                "spread:pad, cx:0.5, cy:0.5,"
                "radius:1.0,fx:0.5, fy:0.5,"
                "stop:0.5 rgb(240, 0, 0),"
                "stop:0.9 grey);"
                "color: rgb(60,0,0);");
        //set to red
        ui->check_status->setText(tr("ERROR"));
        ui->ignition_button->setEnabled(false);
    }
}

void MainWindow::activateStatusChanged(bool isActivated)
{
    if(isActivated)
    {
        activateTimer->stop();

        //ui->statusBar->showMessage(tr("Activated"));
        //ui->statusBar->setStyleSheet("color: black;");

        ui->remote_status->setStyleSheet(
            "border: 2px solid rgb(80,50,0);"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
                "qradialgradient(spread:pad, cx:0.5, cy:0.5,"
                 "radius:0.7, fx:0.5, fy:0.5,"
                 "stop:0.5 rgb(255, 170, 0), "
                 "stop:0.9 grey);"
            "color: rgb(80,50,0);");
        //light on
        ui->remote_status->setText(tr("ONLINE"));
        checkStatusChanged(false);
        lockStatusChanged(true);
        ui->check_button->setEnabled(true);
        ui->unlock_button->setEnabled(true);
        ui->ignition_button->setEnabled(true);
    }
    else
    {
        uart->close();

        ui->statusBar->showMessage(tr("Enter standby status"));
        ui->statusBar->setStyleSheet("color: black;");

        ui->remote_status->setStyleSheet(
            "border: 2px solid black;"
            "border-radius: 4px;"
            "margin: 3px;"
            "background-color:"
                 "grey;"
            "color: black");
        //light off
        ui->remote_status->setText(tr("STANDBY"));
        checkStatusChanged(false);
        lockStatusChanged(true);
        ui->lock_status->setStyleSheet(
                    "border: 2px solid black;"
                    "border-radius: 4px;"
                    "margin: 3px;"
                    "background-color:"
                         "grey;"
                    "color: black;");
        //light off
        ui->check_status->setStyleSheet(
                    "border: 2px solid black;"
                    "border-radius: 4px;"
                    "margin: 3px;"
                    "background-color:"
                         "grey;"
                    "color: black;");
        //light off
        ui->unlock_button->setEnabled(false);
        ui->check_button->setEnabled(false);
        ui->ignition_button->setEnabled(false);
    }
}

void MainWindow::configStatusChanged(bool isValid)
{
    if(!isValid)
        activateStatusChanged(false);
    ui->activate_button->setEnabled(isValid);

    if(isValid)
    {
        ui->statusBar->showMessage(tr("%1 %2,Serial ok")
                                   .arg(uart->portName()).arg(uart->modeString));
        ui->statusBar->setStyleSheet("color: black;");
    }
    else
    {
        ui->statusBar->showMessage(tr("%1 %2,Serial error")
                                   .arg(uart->portName()).arg(uart->modeString));
        ui->statusBar->setStyleSheet("color: red;");
    }
}

void MainWindow::setUnlockPassword(QString &pw)
{
    unlockPasswd = pw;
}

void MainWindow::setIgnitionPassword(QString &pw)
{
    ignitionPasswd = pw;
}

void MainWindow::on_activate_button_clicked()
{
    uart->open(QIODevice::ReadWrite);

    if(uart->isOpen())
    {
        ui->statusBar->showMessage(tr("Send activate cmd"),
                                   sendMsgDisplayTime);
        ui->statusBar->setStyleSheet("color: blue;");

        activateCount = 5;
        sendActivatePacket();
    }
    else
    {
        ui->statusBar->showMessage(tr("%1 open failed, check Serial")
                                   .arg(uart->portName()));
        ui->statusBar->setStyleSheet("color: red;");
    }

}

void MainWindow::on_stby_button_clicked()
{
    activateTimer->stop();

    ui->statusBar->showMessage(tr("Send standby cmd"),
                               sendMsgDisplayTime);
    ui->statusBar->setStyleSheet("color: blue;");

    uart->write("$SYSDOWN\n");
    uart->flush();

}

void MainWindow::on_check_button_clicked()
{
    ui->statusBar->showMessage(tr("Send check cmd"),
                               sendMsgDisplayTime);
    ui->statusBar->setStyleSheet("color: blue;");

    uart->write("$CHECK\n");
    uart->flush();
}

void MainWindow::on_unlock_button_clicked()
{
    if(ui->unlock_button->text() == tr("RELOCK"))
    {
        ui->statusBar->showMessage(tr("Send relock cmd"),
                               sendMsgDisplayTime);
        ui->statusBar->setStyleSheet("color: blue;");

        uart->write("$RELOCK\n");
        uart->flush();
    }
    if(ui->unlock_button->text() == tr("UNLOCK"))
    {
        ui->statusBar->showMessage(tr("Send unlock cmd"),
                               sendMsgDisplayTime);
        ui->statusBar->setStyleSheet("color: blue;");

        uart->write("$UNLOCK,");
        uart->write(unlockPasswd.toAscii());
        uart->write("\n");
        uart->flush();
    }
}

void MainWindow::on_ignition_button_pressed()
{
    ui->statusBar->showMessage(tr("Send ignition cmd"),
                           sendMsgDisplayTime);
    ui->statusBar->setStyleSheet("color: blue;");

    uart->write("$IGNITION,");
    uart->write(ignitionPasswd.toAscii());
    uart->write("\n");
    uart->flush();
}

void MainWindow::sendActivatePacket(void)
{
    activateCount--;

    uart->write("$ACTIVATE\n");
    uart->flush();

    ui->statusBar->showMessage(tr("Try activate: %1")
                               .arg(activateCount));
    ui->statusBar->setStyleSheet("color: blue;");

    if(activateCount > 0)
        activateTimer->start(activateInterval);
    else
    {
        activateCount = 0;
        ui->statusBar->showMessage(tr("No response"));
        ui->statusBar->setStyleSheet("color: red;");
    }
    //qDebug() <<"try activate "<<activateCount;
}

void MainWindow::newMsgReceived()
{
    QByteArray bytes(uart->readLine());
    if(bytes.isEmpty())
        return;
    QString msg(bytes);
    if(     msg.startsWith("#IGNITER,ACTIVATE,OK"))
        emit setActivateStatus(true);
    else if(msg.startsWith("#IGNITER,SYSDOWN"))
        emit setActivateStatus(false);
    else if(msg.startsWith("#IGNITER,UNLOCK,ERR:"))
    {
        msg.remove("#IGNITER,UNLOCK,");
        if(msg.startsWith("ERR:CHECK_FIRST"))
        {
            emit setLockStatus(true);
            ui->statusBar->showMessage(tr("Please check first"));
            ui->statusBar->setStyleSheet("color: red;");
        }
        else if(msg.startsWith("ERR:INTERNAL"))
        {
            emit setActivateStatus(false);
            ui->statusBar->showMessage(tr("Internal error"));
            ui->statusBar->setStyleSheet("color: red");
        }
        else if(msg.startsWith("ERR:KEY"))
        {
            emit setLockStatus(true);
            ui->statusBar->showMessage(tr("Unlock key error"));
            ui->statusBar->setStyleSheet("color: red");
        }
        else
        {
            emit setActivateStatus(false);
            ui->statusBar->showMessage(tr("Unknown: ")+msg);
            ui->statusBar->setStyleSheet("color: red");
        }
    }
    else if(msg.startsWith("#IGNITER,UNLOCK,OK"))
    {
        emit setLockStatus(false);
    }
    else if(msg.startsWith("#IGNITER,RELOCK"))
    {
        emit setLockStatus(true);
    }
    else if(msg.startsWith("#IGNITER,IGNITION,ERR"))
    {
        emit setActivateStatus(false);
        ui->statusBar->showMessage(tr("Ignition error"));
        ui->statusBar->setStyleSheet("color: red;");
    }
    else if(msg.startsWith("#IGNITER,CHECK,OK"))
    {
        emit setCheckStatus(true);
    }
    else if(msg.startsWith("#IGNITER,CHECK,ERR"))
    {
        emit setCheckStatus(false);
    }
    else if(msg.startsWith("#IGNITER,IGNITION,START"))
    {
        ui->statusBar->showMessage(tr("Ignition start"),sendMsgDisplayTime);
        ui->statusBar->setStyleSheet("color: rgb(255,170,0);"
                                     "font-style: bold;");
    }
    else
    {
        ui->statusBar->showMessage(tr("Unknown response"));
        ui->statusBar->setStyleSheet("color: red;");
    }
}
